package com.enjoy.xbase.xui.list;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.enjoy.xbase.R;
import com.enjoy.xbase.xui.adapter.BaseRvAdapter;
import com.enjoy.xbase.xui.adapter.BaseRvViewHolder;
import com.enjoy.xbase.xui.listener.ILoadRefresh;
import com.enjoy.xbase.xui.load.BaseLoad;
import com.enjoy.xbase.xui.load.DefaultLoad;
import com.enjoy.xbase.xui.load.LoadView;
import com.scwang.smart.refresh.layout.SmartRefreshLayout;
import com.scwang.smart.refresh.layout.api.RefreshLayout;
import com.scwang.smart.refresh.layout.listener.OnLoadMoreListener;
import com.scwang.smart.refresh.layout.listener.OnRefreshListener;

import java.util.ArrayList;
import java.util.List;

/**
 * 描述：
 * 通用加载列表类数据基类
 * 介绍：
 * 1、定制加载页面通过在onInitComplete()方法中设置加载交互器完成setLoadMutual()
 */
public abstract class XXBaseListFragment extends Fragment implements BaseRvAdapter.IDataView {
    protected View rootView;
    protected LoadView loadView;
    protected SmartRefreshLayout refreshLayout;
    protected RecyclerView recyclerView;
    protected BaseRvAdapter adapter;

    //内部管理
    protected List data = new ArrayList();
    protected int page = 0;//从第一页开始
    private boolean initComplete = false;
    private boolean hasFooter;
    private boolean mNoMoreData;

    //外部传入数据
    private int outPage = 0;
    private List outData = new ArrayList();
    private boolean outEnd = false;
    private Object outParam;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if (rootView == null) {
            rootView = inflater.inflate(R.layout.xbase_fragment_base_list_v3, container, false);
            initBaseView();
            initBaseListener();
            onInitBaseComplete();
            onInitBaseData();
        }
        return rootView;
    }

    protected final void initBaseView() {
        loadView = rootView.findViewById(R.id.v_load);
        refreshLayout = rootView.findViewById(R.id.refresh);
        recyclerView = rootView.findViewById(R.id.list);
        /**
         * 初始化列表
         */
        int column = getColumn();
        if (column == 1 || column == -1) {
            //创建LinearLayoutManager 对象 这里使用 LinearLayoutManager 是线性布局的意思
            LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
            linearLayoutManager.setOrientation(column > 0 ? RecyclerView.VERTICAL : RecyclerView.HORIZONTAL);
            //设置RecyclerView 布局
            recyclerView.setLayoutManager(linearLayoutManager);
        } else {
            //布局管理器所需参数，上下文
            GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), Math.abs(column));
            //B 通过布局管理器，可以控制条目排列顺序  true：反向显示  false：正常显示(默认)
            gridLayoutManager.setReverseLayout(false);
            //C 设置RecyclerView显示的方向，是水平还是垂直！！ GridLayoutManager.VERTICAL(默认) false
            gridLayoutManager.setOrientation(column > 0 ? RecyclerView.VERTICAL : RecyclerView.HORIZONTAL);
            gridLayoutManager.setAutoMeasureEnabled(true);
            recyclerView.setLayoutManager(gridLayoutManager);
        }
        //设置Adapter
        adapter = new BaseRvAdapter(getContext(), new BaseRvAdapter.IDataView() {
            @Override
            public int getItemCount() {
                int count = XXBaseListFragment.this.getItemCount();
                if (mNoMoreData && hasFooter && count > 0) {
                    return count + 1;
                } else {
                    return count;
                }
            }

            @Override
            public int getItemViewType(int position) {
                if (mNoMoreData && hasFooter && getItemCount() - 1 == position) {
                    return -1;
                } else {
                    return XXBaseListFragment.this.getItemViewType(position);
                }
            }

            @Override
            public int getItemLayoutId(int viewType) {
                if (mNoMoreData && hasFooter && viewType == -1) {
                    return XXBaseListFragment.this.getItemFooterLayoutId();
                } else {
                    return XXBaseListFragment.this.getItemLayoutId(viewType);
                }
            }

            @Override
            public void onBindViewHolder(BaseRvViewHolder holder, int position) {
                if (mNoMoreData && hasFooter && getItemCount() == position + 1) {

                } else {
                    XXBaseListFragment.this.onBindViewHolder(holder, position);
                }
            }
        });
        recyclerView.setAdapter(adapter);
        refreshLayout.setEnableLoadMore(canLoadMore());
        refreshLayout.setEnableRefresh(canRefresh());
    }

    public void setLoad(BaseLoad load) {
        loadView.setLoad(load);
    }

    public void setHasFooter(boolean hasFooter) {
        this.hasFooter = hasFooter;
        adapter.notifyDataSetChanged();
    }

    protected final void initBaseListener() {
        //设置刷新事件
        loadView.setLoadRefresh(new ILoadRefresh() {
            @Override
            public void onRefresh() {
                requestData(page = 0);
            }
        });
        refreshLayout.setOnRefreshListener(new OnRefreshListener() {
            @Override
            public void onRefresh(@NonNull RefreshLayout refreshLayout) {
                requestData(page = 0);
            }
        });
        refreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() {
            @Override
            public void onLoadMore(@NonNull RefreshLayout refreshLayout) {
                requestData(++page);
            }
        });
    }

    /**
     * 初始化完成
     */
    public void onInitBaseComplete() {
        loadView.setLoad(new DefaultLoad());
    }

    /**
     * 描述：准备数据
     */
    protected void onInitBaseData() {
        initComplete = true;
        if (autoLoadData()) {
            loadView.showLoad();
            requestData(page = 0);
        } else {
            initComplete();
        }
    }

    /**
     * 返回列数
     */
    protected int getColumn() {
        return 1;
    }

    /**
     * 描述：是否自动刷新数据
     *
     * @return
     */
    protected boolean autoLoadData() {
        return true;
    }

    /**
     * 是否支持加载更多
     */
    protected boolean canLoadMore() {
        return false;
    }

    /**
     * 是否支持刷新
     */
    protected boolean canRefresh() {
        return false;
    }

    public RecyclerView getRecyclerView() {
        return recyclerView;
    }

    /**
     * 描述：获取适配器
     *
     * @return
     */
    public BaseRvAdapter getAdapter() {
        return adapter;
    }

    /**
     * 描述：设置数据层颜色
     */
    protected void setDataBackgroundColor(@ColorInt int color) {
        if (recyclerView != null) recyclerView.setBackgroundColor(color);
    }

    /**
     * 描述： 返回是否滑动到顶部
     */
    public boolean isToTop() {
        if (recyclerView != null) {
            return !recyclerView.canScrollVertically(-1);
        }
        return true;
    }

    /**
     * 描述：返回是否滑动到底部
     *
     * @return
     */
    public boolean isToBottom() {
        if (recyclerView != null) {
            return !recyclerView.canScrollVertically(1);
        }
        return true;
    }

    public void refreshData() {
        if (loadView != null) {
            requestData(page = 0);
        }
    }

    public void refreshAndLoad() {
        if (loadView != null) {
            loadView.showLoad();
            requestData(page = 0);
        }
    }

    public void refreshAndLoading() {
        if (loadView != null) {
            loadView.showLoading();
            requestData(page = 0);
        }
    }

    /**
     * 描述：设置外部传入数据
     *
     * @param page  页码 从0开始
     * @param data
     * @param param 携带参数将传入load展示
     */
    public synchronized void setOutData(int page, List data, Object param) {
        setOutData(page, data, false, param);
    }

    /**
     * 描述：设置外部传入数据
     *
     * @param page  页码 从0开始
     * @param data
     * @param end   是否结束
     * @param param 携带参数将传入load展示
     */
    public synchronized void setOutData(int page, List data, boolean end, Object param) {
        if (initComplete) {
            this.page = page;
            if (page == 0) {
                if (data == null) {
                    this.data.clear();
                    this.notifyDataSetChanged();
                    loadView.showFail(param);
                } else {
                    if (data.size() == 0) {
                        loadView.showEmpty(param);
                        setNoMoreData(true);
                    } else {
                        setNoMoreData(end);
                        loadView.showData();
                    }
                    this.data.clear();
                    this.data.addAll(data);
                    this.notifyDataSetChanged();
                }
                refreshLayout.finishRefresh();
            } else {
                if (data == null) {
                    --this.page;
                    loadView.showData();
                } else if (data.size() == 0) {
                    setNoMoreData(true);
                    loadView.showData();
                } else {
                    this.data.addAll(data);
                    this.notifyDataSetChanged();
                    loadView.showData();
                    setNoMoreData(end);
                }
                refreshLayout.finishLoadMore();
            }
        } else {
            this.outPage = page;
            this.outEnd = end;
            if (page == 0) {
                if (data == null) {
                    this.outData = null;
                    this.outParam = param;
                } else {
                    this.outParam = param;
                    this.outData.clear();
                    this.outData.addAll(data);
                }
            } else {
                if (data == null) {
                    --this.page;
                } else {
                    this.outData.addAll(data);
                }
            }
        }
    }

    private synchronized void initComplete() {
        if (this.outData == null) {
            loadView.showFail(outParam);
        } else if (this.outData.size() == 0) {
            loadView.showEmpty(outParam);
        } else {
            this.page = outPage;
            this.data.addAll(outData);
            this.notifyDataSetChanged();
            loadView.showData();
            setNoMoreData(outEnd);
        }
    }

    protected void setRequestData(int page, List data) {
        setRequestData(page, data, null);
    }

    /**
     * 描述：设置请求后的数据
     *
     * @param page
     * @param data null-失败
     */
    protected void setRequestData(int page, List data, Object param) {
        if (page == 0) {
            if (data == null) {
                this.data.clear();
                this.notifyDataSetChanged();
                loadView.showFail(param);
            } else {
                if (data.size() == 0) {
                    setNoMoreData(true);
                    loadView.showEmpty(param);
                } else {
                    setNoMoreData(false);
                    loadView.showData();
                }
                this.data.clear();
                this.data.addAll(data);
                this.notifyDataSetChanged();
            }
            refreshLayout.finishRefresh();
        } else {
            if (data == null) {
                --this.page;
                loadView.showData();
            } else if (data.size() == 0) {
                setNoMoreData(true);
                this.notifyDataSetChanged();
                loadView.showData();
            } else {
                setNoMoreData(false);
                this.data.addAll(data);
                this.notifyDataSetChanged();
                loadView.showData();
            }
            refreshLayout.finishLoadMore();
        }
    }

    public <T> T getData(int position) {
        return (T) data.get(position);
    }

    public <T> List<T> getAllData() {
        return data;
    }

    public void removeData(Object object) {
        data.remove(object);
        if (data.size() == 0) {
            loadView.showEmpty();
        }
        notifyDataSetChanged();
    }

    public void setNoMoreData(boolean noMoreData) {
        this.mNoMoreData = noMoreData;
        if (noMoreData) {
            refreshLayout.setEnableLoadMore(false);
        } else {
            if (canLoadMore()) {
                refreshLayout.setEnableLoadMore(true);
            }
        }
        if (adapter != null) {
            adapter.notifyDataSetChanged();
        }
    }

    public void setEnableLoadMore(boolean enable) {
        refreshLayout.setEnableLoadMore(enable);
    }

    public void notifyDataSetChanged() {
        adapter.notifyDataSetChanged();
    }

    /**
     * 请求数据
     * 请求完成后需调用setRequestData(page,data)方法
     */
    protected abstract void requestData(int page);

    @Override
    public int getItemCount() {
        return data.size();
    }

    @Override
    public int getItemViewType(int position) {
        return 0;
    }

    @Override
    public abstract int getItemLayoutId(int viewType);

    protected int getItemFooterLayoutId() {
        return -1;
    }

    @Override
    public abstract void onBindViewHolder(BaseRvViewHolder holder, int position);
}
